package mn.idax.exchange.otc.web;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Maps;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import mn.idax.exchange.common.bean.ResponseData;
import mn.idax.exchange.otc.annotation.LoginAuth;
import mn.idax.exchange.otc.constant.RequestUrlConstant;
import mn.idax.exchange.otc.domain.AdMarketPrice;
import mn.idax.exchange.otc.entity.OTCAds;
import mn.idax.exchange.otc.enums.AdEnum;
import mn.idax.exchange.otc.enums.response.OTCAdResponseEnum;
import mn.idax.exchange.otc.exception.IdaxException;
import mn.idax.exchange.otc.service.OTCAdsService;
import mn.idax.exchange.otc.service.impl.MemoryService;
import mn.idax.exchange.otc.util.LogUtils;
import mn.idax.exchange.otc.vo.ADRecommendListResult;
import mn.idax.exchange.otc.vo.FloatingPriceDTO;
import mn.idax.exchange.otc.vo.OTCAdPageSecDTO;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Create by jack_huang on 2018/11/23
 */

@Api(value = "广告v2接口",tags={"广告v2接口"})
@RestController
@RequestMapping("/api/v2/ad")
public class AdSecController {

    private static final org.slf4j.Logger logger = LoggerFactory.getLogger(AdSecController.class);

    @Autowired
    private OTCAdsService otcAdsService;
    //以下內容待app端修復后均可刪除
    private static final List<String> DICTIONARY_ALIPAY = Arrays.asList("ALIPAY", "支付宝");


    /**
     * 获取币种最高收购价格
     * @param
     * @throws Exception
     */
    @ApiOperation(value = "获取币种最高收购价格", notes = "获取币种最高收购价格，购买时拿最高价，type = 2")
    @RequestMapping(value = RequestUrlConstant.AD_GET_MAX_PRICE,method = RequestMethod.POST)
    @LoginAuth(disable = true)
    public ResponseData getMaxPrice(@RequestBody AdMarketPrice adMarketPrice) throws Exception {

        if (StringUtils.isEmpty(adMarketPrice.getUnit())){
            throw new IdaxException(OTCAdResponseEnum.PAYMETHOD_UNIT_EMPTY.getCode());
        }

        List<OTCAds> ads = otcAdsService.getMarketMaxPrice(adMarketPrice);
        Map<String, BigDecimal> map = getMarketAdTopPrice(ads,AdEnum.type_buy.getCode());
        return ResponseData.success(map);
    }



    /**
     * 获取币种最低收购价格
     * @param
     * @throws Exception
     */
    @ApiOperation(value = "获取币种最低收购价格", notes = "获取币种最低出售价格，出售时拿最低价，type = 1")
    @RequestMapping(value = RequestUrlConstant.AD_GET_MIN_PRICE,method = RequestMethod.POST)
    @LoginAuth(disable = true)
    public ResponseData getMinPrice(@RequestBody AdMarketPrice adMarketPrice) throws Exception {

        if (StringUtils.isEmpty(adMarketPrice.getUnit())){
            throw new IdaxException(OTCAdResponseEnum.PAYMETHOD_UNIT_EMPTY.getCode());
        }
        List<OTCAds> ads = otcAdsService.getMarketMinPrice(adMarketPrice);
        Map<String, BigDecimal> map = getMarketAdTopPrice(ads,AdEnum.type_sell.getCode());
        return ResponseData.success(map);
    }

    /**
     * 获取市场中广告的最低价或最高价
     * @param ads
     * @return
     * @throws Exception
     */
    private Map<String, BigDecimal> getMarketAdTopPrice(List<OTCAds> ads,Integer adType) throws Exception {
        Map<String, BigDecimal> map = new HashMap<String, BigDecimal>();
        BigDecimal topPrice = BigDecimal.ZERO;
        if (ads.isEmpty()){
            topPrice = topPrice;
        } else {
            //需要丟給前端的價格 发布出售广告显示最低，发布购买广告，显示最高
            BigDecimal price = BigDecimal.ZERO;

            if (adType.equals(AdEnum.type_buy.getCode())){
                for (OTCAds otcAds : ads) {
                    if (otcAds.getIsfloating()){
                        price = otcAdsService.floatingAdsPriceConvert(
                                new FloatingPriceDTO(otcAds.getType(), otcAds.getMinprice(), otcAds.getMaxprice(),
                                        otcAds.getUnit(), otcAds.getExchange(), otcAds.getPairname(), otcAds.getPrice(), otcAds.getFloatingrate())
                        ).getPrice();
                    } else {
                        price = otcAds.getPrice();
                    }
                    topPrice = topPrice.compareTo(price) > 0 ? topPrice : price;
                }

            } else {
                if (ads.get(0).getIsfloating()){
                    topPrice = otcAdsService.floatingAdsPriceConvert(
                            new FloatingPriceDTO(ads.get(0).getType(), ads.get(0).getMinprice(), ads.get(0).getMaxprice(),
                                    ads.get(0).getUnit(), ads.get(0).getExchange(), ads.get(0).getPairname(), ads.get(0).getPrice(), ads.get(0).getFloatingrate())
                    ).getPrice();
                } else {
                    topPrice = ads.get(0).getPrice();
                }

                for (OTCAds otcAds : ads) {
                    if (otcAds.getIsfloating()){
                        price = otcAdsService.floatingAdsPriceConvert(
                                new FloatingPriceDTO(otcAds.getType(), otcAds.getMinprice(), otcAds.getMaxprice(),
                                        otcAds.getUnit(), otcAds.getExchange(), otcAds.getPairname(), otcAds.getPrice(), otcAds.getFloatingrate())
                        ).getPrice();
                    } else {
                        price = otcAds.getPrice();
                    }
                    topPrice = topPrice.compareTo(price) > 0 ? price : topPrice;
                }

            }

        }
        map.put("price", topPrice);
        return map;
    }

    private static final List<String> DICTIONARY_WEIXIN = Arrays.asList("WECHAT", "WEIXIN", "微信");
    private static final List<String> DICTIONARY_BANK = Arrays.asList("BANK CARD", "银行卡", "은행 카드");
    private static final String ALL_TYPE = "全部";

    @ApiOperation(value = "获取广告列表", notes = "获取广告列表，(shihaiming，自测通过)")
    @RequestMapping(value = RequestUrlConstant.AD_LIST, method = RequestMethod.POST)
    public ResponseData list(@RequestBody OTCAdPageSecDTO otcAdPageDTO) throws Exception {

        Map<String, Object> map = Maps.newHashMap();
        List<ADRecommendListResult> adList = MemoryService.AD_LIST.get("adList");


        if (CollectionUtils.isEmpty(adList)){
            map.put("data", adList);
            map.put("total", 0);
            return ResponseData.success(map);
        }

        //add for hot_fix
        try {
            this.dataTransfer(otcAdPageDTO);
        } catch (Exception e) {
            logger.warn("adListQueryError : {},{}", JSON.toJSONString(otcAdPageDTO), ExceptionUtils.getStackTrace(e));
        }

        adList = adList.stream()
                .filter(p -> Objects.isNull(otcAdPageDTO.getCountry()) || otcAdPageDTO.getCountry().equals(p.getCountry()))
                .filter(p -> StringUtils.isEmpty(otcAdPageDTO.getUnit()) || otcAdPageDTO.getUnit().equals(p.getUnit()))
                .filter(p -> StringUtils.isEmpty(otcAdPageDTO.getPairname()) || otcAdPageDTO.getPairname().equals(p.getPairname()))
                .filter(p -> StringUtils.isEmpty(otcAdPageDTO.getTransactionWayList()) || p.getTransactionWayList().contains(otcAdPageDTO.getTransactionWayList()))
                .collect(Collectors.toList());


        List<ADRecommendListResult> list = new ArrayList<>();


        LogUtils.info(this.getClass(),"adsecController adList data :" + JSON.toJSONString(adList));

        //价格 好评（相同时，商家排名优先）
        if (otcAdPageDTO.getType().equals(AdEnum.type_buy.getCode())) {

            //从内存中取出符合条件的数据 三个条件必传
           list = adList.stream()
                    .filter(p -> AdEnum.type_buy.getCode().equals(p.getType()))
                    .collect(Collectors.toList());
            // 2降序
            Collections.sort(list, new Comparator<ADRecommendListResult>() {
                @Override
                public int compare(ADRecommendListResult o1, ADRecommendListResult o2) {
                    int result = -(new BigDecimal(o1.getPrice()).compareTo(new BigDecimal(o2.getPrice())));
                    if (result == 0) {
                        result = (o1.getUpdateTime().compareTo(o2.getUpdateTime()));
                    }
                    return result;
                }
            });

        } else {
            //从内存中取出符合条件的数据 三个条件必传
           list = adList.stream().filter(p -> AdEnum.type_sell.getCode().equals(p.getType())).collect(Collectors.toList());
            // 1升序
            Collections.sort(list, new Comparator<ADRecommendListResult>() {
                @Override
                public int compare(ADRecommendListResult o1, ADRecommendListResult o2) {
                    int result = new BigDecimal(o1.getPrice()).compareTo(new BigDecimal(o2.getPrice()));
                    if (result == 0) {
                        result = (o1.getUpdateTime().compareTo(o2.getUpdateTime()));
                    }
                    return result;
                }
            });
        }

        Integer pageIndex = otcAdPageDTO.getPageIndex();
        Integer pageSize = otcAdPageDTO.getPageSize();

        if (pageIndex == null || pageIndex < 0) {
            pageIndex = 0;
        }
        //防止用户恶意攻击
        if (pageSize == null || pageSize <= 0 || pageSize > 1000) {
            pageSize = 1000;
        }

        Integer start = pageSize * pageIndex;

        if (list.isEmpty() || start >= list.size()){
            ArrayList<ADRecommendListResult> beyondResults = new ArrayList<>();
            map.put("data", beyondResults);
            map.put("total", list.size());
            return ResponseData.success(map);
        }

        Integer end = pageSize * pageIndex + pageSize;
        if (end > list.size()){
            end = list.size();
        }

        //返回分页的数据
        List<ADRecommendListResult> adRecommendListResults = list.subList(start, end);

        map.put("data", adRecommendListResults);
        map.put("total", list.size());
        return ResponseData.success(map);

    }

    private OTCAdPageSecDTO dataTransfer(OTCAdPageSecDTO otcAdPageSecDTO) {

        if (StringUtils.isEmpty(otcAdPageSecDTO.getTransactionWayList())) {
            otcAdPageSecDTO.setTransactionWayList(null);
            return otcAdPageSecDTO;
        }

        if (isInteger(otcAdPageSecDTO.getTransactionWayList())) {
            return otcAdPageSecDTO;
        }

        otcAdPageSecDTO.setTransactionWayList(otcAdPageSecDTO.getTransactionWayList().toUpperCase());

        //支付方式 (1-支付宝 2-微信 3-银行)d
        if (DICTIONARY_ALIPAY.contains(otcAdPageSecDTO.getTransactionWayList())) {
            otcAdPageSecDTO.setTransactionWayList("1");
        } else if (DICTIONARY_WEIXIN.contains(otcAdPageSecDTO.getTransactionWayList())) {
            otcAdPageSecDTO.setTransactionWayList("2");
        } else if (DICTIONARY_BANK.contains(otcAdPageSecDTO.getTransactionWayList())) {
            otcAdPageSecDTO.setTransactionWayList("3");
        } else if (ALL_TYPE.equalsIgnoreCase(otcAdPageSecDTO.getTransactionWayList())) {
            otcAdPageSecDTO.setTransactionWayList(null);
        }

        switch (otcAdPageSecDTO.getTransactionWayList()) {
            case "PAYPAL":
                otcAdPageSecDTO.setTransactionWayList("4");
            case "KAKAOPAY":
                otcAdPageSecDTO.setTransactionWayList("5");
            case "NAVERPAY":
                otcAdPageSecDTO.setTransactionWayList("6");
            case "PAYNOW":
                otcAdPageSecDTO.setTransactionWayList("7");
            case "ZALOPAY":
                otcAdPageSecDTO.setTransactionWayList("8");
        }

        return otcAdPageSecDTO;
    }

    private boolean isInteger(Object object) {
        try {
            Integer.valueOf(object.toString());
            return true;
        } catch (Exception e) {
            return false;
        }
    }

}
